package cn.exrick.service.impl;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.IndicesAdminClient;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.google.gson.Gson;

import cn.exrick.common.exception.XmallException;
import cn.exrick.mapper.TbItemMapper;
import cn.exrick.pojo.TbItemSkuGoodCat;
import cn.exrick.pojo.TbItemSkuGoodCatAttr;
import cn.exrick.pojo.dto.EsCount;
import cn.exrick.pojo.dto.EsInfo;
import cn.exrick.pojo.dto.ItemDto;
import cn.exrick.pojo.front.SearchItem;
import cn.exrick.service.ItemService;
import cn.exrick.service.ItemSkuGoodCatAttrService;
import cn.exrick.service.ItemSkuGoodCatService;
import cn.exrick.service.SearchItemService;
import cn.exrick.utils.HttpUtil;

/**
 * @author Exrickx
 */
@Service
public class SearchItemServiceImpl implements SearchItemService {

    private final static Logger log = LoggerFactory.getLogger(SearchItemServiceImpl.class);

    @Autowired
    private TbItemMapper itemMapper;

    @Autowired
    private ItemService itemService;

    @Autowired
    private ItemSkuGoodCatService itemSkuGoodCatService;

    @Autowired
    private ItemSkuGoodCatAttrService itemSkuGoodCatAttrService;


    @Value("${ES_CONNECT_IP}")
    private String ES_CONNECT_IP;

    @Value("${ES_NODE_CLIENT_TCP_PORT}")
    private String ES_NODE_CLIENT_TCP_PORT;

    @Value("${ES_NODE_CLIENT_HTTP_PORT}")
    private String ES_NODE_CLIENT_HTTP_PORT;

    @Value("${ES_CLUSTER_NAME}")
    private String ES_CLUSTER_NAME;

    @Value("${ITEM_INDEX}")
    private String ITEM_INDEX;

    @Value("${ITEM_TYPE}")
    private String ITEM_TYPE;

    @Override
    public int importAllItems() {

        try {
            Settings settings = Settings.builder()
                    .put("cluster.name", ES_CLUSTER_NAME).build();
            TransportClient client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ES_CONNECT_IP), Integer.parseInt(ES_NODE_CLIENT_TCP_PORT)));

            // 删除索引
            try {
                IndicesAdminClient adminClient = client.admin().indices();
                IndicesExistsRequest request = new IndicesExistsRequest(ITEM_INDEX);
                IndicesExistsResponse response = adminClient.exists(request).actionGet();
                if (response.isExists()) {
                    log.info("elasticsearch index [{}] is exist, execute delete index", ITEM_INDEX);
                    DeleteIndexRequest deleteRequest = new DeleteIndexRequest(ITEM_INDEX);
                    DeleteIndexResponse deleteResponse = adminClient.delete(deleteRequest).actionGet();
                    if(deleteResponse.isAcknowledged()){
                        log.info("elasticsearch delete index[{}] success", ITEM_INDEX);
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                log.info("elasticsearch delete index[{}] error", ITEM_INDEX);
            }

            //批量添加
            BulkRequestBuilder bulkRequest = client.prepareBulk();

            //查询商品列表
            List<SearchItem> itemList = itemMapper.getItemList();
            if(itemList == null|| itemList.size()<=0){
                return 1;
            }
            log.info("获取商品成功:" + itemList.size());

            List<Long> addedIds = new ArrayList<>();

            //遍历商品列表
            for (SearchItem searchItem : itemList) {
                String image = searchItem.getProductImageBig();
                if (image != null && !"".equals(image)) {
                    String[] strings = image.split(",");
                    image = strings[0];
                } else {
                    image = "";
                }
                searchItem.setProductImageBig(image);

                if (addedIds.contains(searchItem.getProductId())) {
                    continue;
                }
                List<ItemDto> itemDtos = itemSkuGoodCatService.findBrotherItem(searchItem.getProductId());//相关联的商品
                String productName = "";
                String categoryName = "";
                double salePrice = 999999999;
                double salePriceMax = 0;
                for (ItemDto itemDto : itemDtos) {
                    TbItemSkuGoodCatAttr itemSkuGoodCatAttr = null;
                    try {
                        itemSkuGoodCatAttr = itemSkuGoodCatAttrService.findByItemId(itemDto.getId());
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                	List<TbItemSkuGoodCat> itemSkuGoodCatList = itemSkuGoodCatAttrService
            				.findOneTreeByAttrId(itemSkuGoodCatAttr.getId());
            		String sku = "[";
            		if (!CollectionUtils.isEmpty(itemSkuGoodCatList)) {
            			for (TbItemSkuGoodCat itemSkuGoodCat : itemSkuGoodCatList) {
            				sku += itemSkuGoodCat.getName() + ":" + itemSkuGoodCat.getAttr().getName() + "-";
            			}
            		}
                    if (sku.endsWith("-")) {
                        sku = sku.substring(0, sku.length() - 1);
                    }
                    sku += "]";
                    itemDto.setSkuTitle(sku);

                    addedIds.add(itemDto.getId());
                    if (!productName.contains(itemDto.getTitle())) {
                        productName += "," + itemDto.getTitle();
                        productName += itemDto.getSkuTitle();
                    }
                    if (!categoryName.contains(itemDto.getCname())) {
                        categoryName += "," + itemDto.getCname();
                    }
                    if (itemDto.getPrice().doubleValue() <= salePrice) {
                        salePrice = itemDto.getPrice().doubleValue();
                    }
                    if (itemDto.getPrice().doubleValue() >= salePriceMax) {
                        salePriceMax = itemDto.getPrice().doubleValue();
                    }
                }
                bulkRequest.add(client.prepareIndex("item", "itemList", String.valueOf(searchItem.getProductId()))
                        .setSource(jsonBuilder()
                                .startObject()
                                .field("productId", searchItem.getProductId())
                                .field("salePrice", salePrice)
                                .field("salePriceMax", salePriceMax)
                                .field("productNameQuery", productName)
                                .field("productName", searchItem.getProductName())
                                .field("subTitle", searchItem.getSubTitle())
                                .field("productImageBig", searchItem.getProductImageBig())
                                .field("categoryName", searchItem.getCategoryName())
                                .field("cid", searchItem.getCid())
                                .field("cName", searchItem.getCategoryName())
                                .endObject()
                        )
                );
            }

            BulkResponse bulkResponse = bulkRequest.get();

            log.info("更新索引成功");

            client.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new XmallException("导入ES索引库出错");
        }

        return 1;
    }

    @Override
    public int refreshItem(int type, Long itemId) {

        try {
            //更新索引
            Settings settings = Settings.builder()
                    .put("cluster.name", ES_CLUSTER_NAME).build();
            TransportClient client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(ES_CONNECT_IP), Integer.parseInt(ES_NODE_CLIENT_TCP_PORT)));

            if (type == 0) {
                //根据商品id查询商品信息
                SearchItem searchItem = itemMapper.getItemById(itemId);
                String image = searchItem.getProductImageBig();
                if (image != null && "".equals(image)) {
                    String[] strings = image.split(",");
                    image = strings[0];
                } else {
                    image = "";
                }
                searchItem.setProductImageBig(image);
                IndexResponse indexResponse = client.prepareIndex(ITEM_INDEX, ITEM_TYPE, String.valueOf(searchItem.getProductId()))
                        .setSource(jsonBuilder()
                                .startObject()
                                .field("productId", searchItem.getProductId())
                                .field("salePrice", searchItem.getSalePrice())
                                .field("original", searchItem.getOriginal())
                                .field("productName", searchItem.getProductName())
                                .field("subTitle", searchItem.getSubTitle())
                                .field("productImageBig", searchItem.getProductImageBig())
                                .field("categoryName", searchItem.getCategoryName())
                                .field("cid", searchItem.getCid())
                                .endObject()
                        ).get();
            } else {
                DeleteResponse deleteResponse = client.prepareDelete(ITEM_INDEX, ITEM_TYPE, String.valueOf(itemId)).get();
            }

            log.info("同步商品：" + itemId + "索引成功");

            client.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return 1;
    }

    @Override
    public EsInfo getEsInfo() {

        String healthUrl = "http://" + ES_CONNECT_IP + ":" + ES_NODE_CLIENT_HTTP_PORT + "/_cluster/health";
        String countUrl = "http://" + ES_CONNECT_IP + ":" + ES_NODE_CLIENT_HTTP_PORT + "/_count";
        String healthResult = HttpUtil.sendGet(healthUrl);
        String countResult = HttpUtil.sendGet(countUrl);
        if (StringUtils.isBlank(healthResult) || StringUtils.isBlank(countResult)) {
            throw new XmallException("连接集群失败，请检查ES运行状态");
        }
        EsInfo esInfo = new EsInfo();
        EsCount esCount = new EsCount();
        try {
            esInfo = new Gson().fromJson(healthResult, EsInfo.class);
            esCount = new Gson().fromJson(countResult, EsCount.class);
            esInfo.setCount(esCount.getCount());
        } catch (Exception e) {
            e.printStackTrace();
            throw new XmallException("获取ES信息出错");
        }

        return esInfo;
    }
}
